package com.meisupic.copyright.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileHashHelper {

  private final static Logger logger = LoggerFactory.getLogger(FileHashHelper.class);

  /**
   * 获取文件文件MD5 Hash值
   * <p>
   *
   * @param fileName 文件绝对地址
   */
  public static String getMD5Hash(String fileName) throws NoSuchAlgorithmException, IOException {
    return getHash(fileName, "MD5");
  }

  /**
   * 获取文件文件MD5 Hash值
   * <p>
   *
   * @param ins 文件输入流
   */
  public static String getMD5Hash(InputStream ins) throws NoSuchAlgorithmException, IOException {
    return getHash(ins, "MD5");
  }

  /**
   * 获取文件文件Hash值
   * <p>
   *
   * @param pathName 文件绝对地址
   * @param hashType MessageDigest 加密算法
   */
  public static String getHash(String pathName, String hashType)
      throws IOException, NoSuchAlgorithmException {
    File f = new File(pathName);
    logger
        .debug(" -------------------------------------------------------------------------------");
    logger.debug("|当前文件名称:" + f.getName());
    logger.debug("|当前文件大小:" + (f.length() / 1024 / 1024) + "MB");
    logger.debug("|当前文件路径[绝对]:" + f.getAbsolutePath());
    logger.debug("|当前文件路径[---]:" + f.getCanonicalPath());
    logger.debug("|当前文件最后一次被修改时间[---]:" + f.lastModified());
    logger
        .debug(" -------------------------------------------------------------------------------");
    return getHash(new FileInputStream(f), hashType);
  }

  /**
   * 获取文件文件Hash值
   * <p>
   *
   * @param ins 文件输入流
   * @param hashType MessageDigest 加密算法
   */
  public static String getHash(InputStream ins, String hashType)
      throws IOException, NoSuchAlgorithmException {
    if (ins == null) {
      // 输入流为空返回 null
      return null;
    }
    byte[] buffer = new byte[8192];
    MessageDigest md5 = MessageDigest.getInstance(hashType);
    try {
      int len;
      while ((len = ins.read(buffer)) != -1) {
        md5.update(buffer, 0, len);
      }
    } catch (Exception e) {
      logger.error("getHash error: ", e);
    } finally {
      ins.close();
    }
    return byte2Hex(md5.digest());
  }

  /**
   * 字节数组转换为 16 进制字符串
   *
   * @param bytes 字节数组
   */
  public static String byte2Hex(byte[] bytes) {
    Formatter formatter = new Formatter();
    for (byte b : bytes) {
      formatter.format("%02x", b);
    }
    String hash = formatter.toString();
    formatter.close();
    return hash;
  }
}
